<!-- 角色权限分配弹窗 -->
<template>
  <RadModal
    title="分配权限"
    :is-update="false"
    :visible="visible"
    :loading="loading"
    @visible-change="updateVisible"
    @ok="save"
  >
    <a-tree
      :checkable="true"
      :fieldNames="{ title: 'title', key: 'id' }"
      :tree-data="(authData as any)"
      v-model:checkedKeys="ownMenuData"
      @check="handleCheck"
    >
      <template #title="{ title, icon }">
        <component v-if="icon" :is="icon" />{{ title }}
      </template>
    </a-tree>
  </RadModal>
</template>

<script lang="ts" setup>
  import { ref, watch, nextTick } from 'vue';
  import { message } from 'ant-design-vue/es';
  import { eachTreeData } from 'ele-admin-pro/es';
  import { updateRoleMenus, ownMenuList } from '@/api/system/role';
  import { listMenus } from '@/api/system/menu';
  import RadModal from '@/components/RadModal/index.vue';

  import type { Role } from '@/api/system/role/model';

  const emit = defineEmits<{
    (e: 'done'): void;
    (e: 'update:visible', visible: boolean): void;
  }>();

  const props = defineProps<{
    // 弹窗是否打开
    visible: boolean;
    // 当前角色数据
    data: Role;
  }>();

  // 权限数据
  const authData = ref<any[]>([]);

  // 权限数据请求状态
  const authLoading = ref(false);

  // 提交状态
  const loading = ref(false);

  const ownMenuData = ref<number[]>([]);
  let checkKeys: number[] = []; // 子节点集合(勾选)
  let halfCheckKeys: number[] = []; // 父节点集合(半勾选)

  /* 查询权限数据 */
  const query = () => {
    authData.value = [];
    if (!props.data) {
      return;
    }
    authLoading.value = true;
    listMenus({})
      .then((data) => {
        authLoading.value = false;
        // 转成树形结构的数据
        authData.value = data as any[];
        // 全部默认展开以及回显选中的数据
        nextTick(async () => {
          eachTreeData(authData.value, (d) => {
            if (d.id) {
              if (d.children.length == 0) {
                d.style = 'display:inline-flex';
              }
            }
          });
          var menuTree = await ownMenuList(props.data.id);
          checkKeys = [];
          halfCheckKeys = [];
          handleKeys(menuTree);
          ownMenuData.value = checkKeys;
        });
      })
      .catch((e) => {
        authLoading.value = false;
        message.error(e.message);
      });
  };
  // 递归遍历树区分父子节点集合
  function handleKeys(menuTree?: any[]) {
    menuTree?.map((item) => {
      if (item.children && item.children.length > 0) {
        halfCheckKeys.push(item.id);
        handleKeys(item.children);
      } else {
        checkKeys.push(item.id);
      }
    });
  }

  // 节点勾选事件
  function handleCheck(_checkedKeys, e) {
    checkKeys = _checkedKeys;
    halfCheckKeys = e.halfCheckedKeys;
  }

  /* 保存权限分配 */
  const save = () => {
    loading.value = true;
    const menuIdList = checkKeys.concat(halfCheckKeys); // 将勾选和半勾选节点合并
    // eachTreeData(authData.value, (d) => {
    //   if (d.key && checkedKeys.value.some((c) => c === d.key)) {
    //     ids.add(d.key);
    //     if (d.parentIds) {
    //       d.parentIds.forEach((id: number) => {
    //         ids.add(id);
    //       });
    //     }
    //   }
    // });
    updateRoleMenus({ id: props.data?.id, menuIdList })
      .then((msg) => {
        loading.value = false;
        message.success(msg);
        updateVisible(false);
        emit('done');
      })
      .catch((e) => {
        loading.value = false;
        message.error(e.message);
      });
  };

  /* 更新visible */
  const updateVisible = (value: boolean) => {
    emit('update:visible', value);
  };

  watch(
    () => props.visible,
    (visible) => {
      if (visible) {
        query();
      }
    }
  );
</script>

<script lang="ts">
  import * as MenuIcons from '@/layout/menu-icons';

  export default {
    components: MenuIcons
  };
</script>
<style>
  .ant-tree-list-holder-inner {
    display: unset !important;
  }

  .ant-tree-node-content-wrapper .ant-tree-title {
    position: relative !important;
  }
</style>
